package io.github.talelin.latticy.common.util;

import com.itextpdf.barcodes.Barcode128;
import com.itextpdf.barcodes.BarcodeQRCode;
import com.itextpdf.barcodes.qrcode.EncodeHintType;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.xobject.PdfFormXObject;
import io.github.talelin.latticy.common.pojo.BarCodeEntity;
import io.github.talelin.latticy.common.pojo.BaseDO;
import io.github.talelin.latticy.dto.oms.product.PrintBarcodeDTO;
import io.github.talelin.latticy.model.oms.ProductDO;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName：生成条码和二维码工具类
 * @Author: ljj
 * @Date: 2022/5/18 14:50
 */
@Slf4j
public class BarCodeToPDF {

    public static void createPDF2(BarCodeEntity barCodeEntity) throws Exception {
        PrintBarcodeDTO printBarcode = barCodeEntity.getPrintBarcode();
        List<PrintBarcodeDTO.productNum> productNums = printBarcode.getProductNums();
        Map<Long, List<ProductDO>> map = barCodeEntity.getProducts()
                .stream().collect(Collectors.groupingBy(BaseDO::getId));
        OutputStream os = barCodeEntity.getFileOutputStream();
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(os));
        for (PrintBarcodeDTO.productNum productNum : productNums) {
            for (Integer i = 0; i < productNum.getNum(); i++) {
                ProductDO product = map.get(productNum.getId()).get(0);
                PdfPage pdfPage = pdfDoc.addNewPage(new PageSize(barCodeEntity.getPageWidth(), barCodeEntity.getPageHeight()));
                PdfCanvas canvas = new PdfCanvas(pdfPage);
                String printCode = getPrintCode(printBarcode, product);
                int width = barCodeEntity.getPageWidth();
                int height = barCodeEntity.getPageHeight();
                BufferedImage barCode = GoogleBarCodeUtils.getBarCode(printCode, barCodeEntity.getPageWidth(), barCodeEntity.getPageHeight()-50);
                ImageIO.write(barCode, "jpg", new File("D:/superMansss.png"));
                BufferedImage image = GoogleBarCodeUtils.insertWords(
                        GoogleBarCodeUtils.getBarCode(printCode, barCodeEntity.getPageWidth()-20, barCodeEntity.getPageHeight()-30),
                        printCode,
                        printBarcode.getProductName() ? product.getName() : null,
                        printBarcode.getEnName() ? product.getEnName() : null,
                        printBarcode.getDate() ? DateUtils.dateStr2(new Date()) : null,
                        printBarcode.getOrigin() ? product.getOrigin() : null,
                        width,
                        height);
                ImageIO.write(image, "jpg", new File("D:/superMan.png"));
                // 字节数组输出流
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                boolean createQRCode = ImageIO.write(image, "png", byteArrayOutputStream);
                if (!createQRCode) {
                    log.error("二维码写入输出流失败");
                    throw new Exception("二维码写入输出流失败");
                }
                ImageData png = ImageDataFactory.createPng(byteArrayOutputStream.toByteArray());
                canvas.addImage(png, barCodeEntity.getAbsoluteX(), barCodeEntity.getAbsoluteY(),barCodeEntity.getPageWidth(), true);
                byteArrayOutputStream.close();
            }
        }
        pdfDoc.close();
    }


    public static void createPDF1(BarCodeEntity barCodeEntity) throws Exception {
        OutputStream os = barCodeEntity.getFileOutputStream();
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(os));
        for (ProductDO product : barCodeEntity.getProducts()) {
            PdfPage pdfPage = pdfDoc.addNewPage(new PageSize(barCodeEntity.getPageWidth(), barCodeEntity.getPageHeight()));
            PdfCanvas canvas = new PdfCanvas(pdfPage);
            BufferedImage image = GoogleBarCodeUtils.insertWords(
                    GoogleBarCodeUtils.getBarCode(product.getSku()),
                    product.getSku(),
                    product.getName(),
                    DateUtils.dateStr2(new Date()),
                    product.getOrigin());
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  // 字节数组输出流
            boolean createQRCode = ImageIO.write(image, "png", byteArrayOutputStream);
            if (!createQRCode) {
                log.error("二维码写入输出流失败");
                throw new Exception("二维码写入输出流失败");
            }
            ImageData png = ImageDataFactory.createPng(byteArrayOutputStream.toByteArray());
            canvas.addImage(png, barCodeEntity.getAbsoluteX(), barCodeEntity.getAbsoluteY(), true);
            byteArrayOutputStream.close();
        }
        pdfDoc.close();
    }


    public static void createPDF(BarCodeEntity barCodeEntity) {
        try {
            OutputStream os = barCodeEntity.getFileOutputStream();
            PdfDocument pdfDoc = new PdfDocument(new PdfWriter(os));
            int size = barCodeEntity.getBarCodeList().size();
            for (int i = 0; i < size; i++) {
                PdfPage pdfPage = pdfDoc.addNewPage(new PageSize(barCodeEntity.getPageWidth(), barCodeEntity.getPageHeight()));
                PdfCanvas canvas = new PdfCanvas(pdfPage);
                PdfFormXObject pdfFormXObject;
                if (barCodeEntity.getType() == 1) {
                    pdfFormXObject = createBarcode1D(barCodeEntity.getBarCodeList().get(i),
                            pdfDoc, barCodeEntity.getCodeSize(), barCodeEntity.getCodeHeight(), barCodeEntity.getCodeBaseline());

                } else {
                    pdfFormXObject = createBarcode2D(barCodeEntity.getBarCodeList().get(i), pdfDoc, barCodeEntity.getModuleSize());
                }
                canvas.addXObject(pdfFormXObject, barCodeEntity.getAbsoluteX(), barCodeEntity.getAbsoluteY(), barCodeEntity.getWidth());
            }
            pdfDoc.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static PdfFormXObject createBarcode1D(String codeMsg, PdfDocument pdfDoc, int codeSize, int codeHeight, int codeBaseline) {
        // Barcode39 code = new Barcode39(pdfDoc);
        Barcode128 code = new Barcode128(pdfDoc);
        code.setSize(codeSize);
        code.setBarHeight(codeHeight);
        code.setCode(codeMsg);
        code.setBaseline(codeBaseline);
        code.setCodeType(Barcode128.CODE128);
        return code.createFormXObject(ColorConstants.BLACK,
                ColorConstants.BLACK,
                pdfDoc);
    }

    private static PdfFormXObject createBarcode2D(String code, PdfDocument pdfDoc, int moduleSize) {
        BarcodeQRCode qrcode = new BarcodeQRCode(code);
        Map<EncodeHintType, Object> HINTS = new HashMap<EncodeHintType, Object>();
        HINTS.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        qrcode.setHints(HINTS);
        return qrcode.createFormXObject(ColorConstants.BLACK,
                moduleSize,
                pdfDoc);
    }

    private static String getPrintCode(PrintBarcodeDTO printBarcode, ProductDO product) {
        String printCodeType = product.getSku();
        switch (printBarcode.getType()) {
            case 1:
                printCodeType = product.getSku();
                break;
            case 2:
                printCodeType = product.getCreatorCode() + product.getSku();
                break;
            case 3:
                //
                printCodeType = product.getSku();
                break;
        }
        return printCodeType;
    }
}